/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @Title: DocumentHandle.java
 * @Package phoenics.apeak.crawl
 * @Description
 * @author phoenics@126com
 * @date 2016-1-30 16:01:30
 * @version V1.0
 */
package phoenics.apeak.crawl;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.Request;

import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.WorkHandler;

import phoenics.apeak.crawl.util.LinkTools;

// TODO: Auto-generated Javadoc
/**
 * The Class DocumentHandle.
 *
 * @Description The Class DocumentHandle.
 */
public class DocumentHandle implements EventHandler<Document>,WorkHandler<Document>{
	
	/** The Constant headSelects. */
	public final static Map<String,Integer> errorMap=new ConcurrentHashMap<>();
	/** The http client. */
	private HttpClient httpClient;
	
	/**
 * The Constructor.
 *
 * @param httpClient
 *            the http client
 * @Description Instantiates a new document handle.
 */
	public DocumentHandle(HttpClient httpClient){
		this.httpClient=httpClient;
	}

	/* (non-Javadoc)
	 * @see com.lmax.disruptor.EventHandler#onEvent(java.lang.Object, long, boolean)
	 */
	@Override
	public void onEvent(Document event, long sequence, boolean endOfBatch) throws Exception {
		this.onEvent(event);
	}

	/* (non-Javadoc)
	 * @see com.lmax.disruptor.WorkHandler#onEvent(java.lang.Object)
	 */
	@Override
	public void onEvent(Document event) throws Exception {
		if(event.isRepeat()){
			int testloop=LinkTools.LinkTest(event.getUrl(),errorMap);
			System.out.println("error4url "+testloop+" tests:"+event.getUrl());
			if(testloop>3){
				errorMap.remove(event.getUrl());
				event.setDealWith(true);
				documentEnd(event);
				return;
			}
		}
		takeContext(event);
	}
	
	/**
 * Take context.
 *
 * @param event
 *            the event
 * @throws Exception
 *             the exception
 * @Description Take context.
 */
	private void takeContext(Document event) throws Exception {
		Request request=getHttpClient().newRequest(event.getUrl());
		request.idleTimeout(15, TimeUnit.SECONDS);
		request.timeout(15, TimeUnit.SECONDS);
		String agent=event.getHead().get(HttpHead.agent);
		if(agent!=null && !agent.equals("")){
			request.agent(agent);
		}
		 request.send(event.getListener());
	}

	/**
 * Gets the http client.
 *
 * @return the http client
 */
	private HttpClient getHttpClient() throws Exception {
		if(!httpClient.isStarted()){
			httpClient.start();
		}
		return httpClient;
	}
	
	private void documentEnd(Document event){
		Extractor e=event.getApplicationContext().getBean(event.getExtractorClass());
		Discard discard=e.getDiscard();
		if(discard==null){
			return;
		}
		discard.colseDocument(event);
	}

}
